package com.unlcn.ils.sales.backend.service;

import cn.huiyunche.commons.constant.QiniuConstant;
import cn.huiyunche.commons.exception.BusinessException;
import cn.huiyunche.commons.utils.QiniuUtil;
import com.google.common.collect.Lists;
import com.unlcn.ils.sales.backend.bo.UserBO;
import com.unlcn.ils.sales.backend.bo.UserViewBO;
import com.unlcn.ils.sales.backend.constant.AutoConfConstant;
import com.unlcn.ils.sales.backend.redis.MindsJedisConnectionFactory;
import com.unlcn.ils.sales.backend.security.JwtAuthenicationFilter;
import com.unlcn.ils.sales.backend.security.JwtUtils;
import com.unlcn.ils.sales.backend.security.domains.UserSecurityVO;
import com.unlcn.ils.sales.base.mapper.SaleUserMapper;
import com.unlcn.ils.sales.base.mapper.SaleUserViewMapper;
import com.unlcn.ils.sales.base.model.SaleUser;
import com.unlcn.ils.sales.base.model.SaleUserExample;
import com.unlcn.ils.sales.base.model.UserViewDAO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created by houjianhui on 2017/6/9.
 */
@Service
public class UserServiceImpl implements UserService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private SaleUserMapper userMapper;

    @Autowired
    private Md5PasswordEncoder passwordEncoder;

    @Autowired
    private MindsJedisConnectionFactory connectionFactory;

    @Autowired
    private SendMessageService sendMessageService;

    @Autowired
    private SaleUserViewMapper userViewMapper;

    @Autowired
    private AutoConfConstant autoConfConstant;

    @Override
    public Map login(String loginName, String pwd) throws Exception {
        LOGGER.info("UserServiceImpl.login prams loginName: {}, pwd: {}", loginName, pwd);

        if (StringUtils.isBlank(loginName)) {
            LOGGER.info("UserServiceImpl.login prams loginName must not be null");
            throw new IllegalArgumentException("用户登录名称不能为空");
        } else if (StringUtils.isBlank(pwd)) {
            LOGGER.info("UserServiceImpl.login prams pwd must not be null");
            throw new IllegalArgumentException("用户登录密码不能为空");
        }

        // 判断用户是否存在
        UserBO userBO = getUserByLoginName(loginName);
        if (Objects.equals(userBO, null)) {
            LOGGER.info("current user is null");
            throw new BusinessException("登录失败");
        }
        String key = autoConfConstant.getSecure();
        if (!passwordEncoder.isPasswordValid(userBO.getPwd(), pwd, key)) {
            LOGGER.info("UserServiceImpl.login pwd is error");
            throw new BusinessException("用户名或密码错误");
        }

        Map map = new HashMap();
        // 生成token
        String token = JwtUtils.generateToken(new UserSecurityVO(Long.valueOf(userBO.getId()), userBO.getLoginName(), userBO.getPwd()), key);
        map.put(JwtAuthenicationFilter.HEADER_AUTHORIZATION, JwtAuthenicationFilter.PREFIX_AUTHORIZATION + token);

        return map;
    }

    @Override
    public UserBO getUserByLoginName(String loginName) throws Exception {
        LOGGER.info("UserServiceImpl.getUserByLoginName param loginName: {}", loginName);
        if (StringUtils.isBlank(loginName)) {
            LOGGER.info("UserServiceImpl.getUserByLoginName param loginName must not be null");
            throw new IllegalArgumentException("登录名称不能为空");
        }
        SaleUserExample example = new SaleUserExample();
        example.createCriteria().andLoginNameEqualTo(loginName).andEnableEqualTo(true);
        List<SaleUser> users = userMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(users)) {
            SaleUser user = users.get(0);
            UserBO bo = new UserBO();
            BeanUtils.copyProperties(user, bo);
            return bo;
        }
        return null;
    }

    @Override
    public String setAuthCode(String phone, String code, int seconds) throws Exception {
        LOGGER.info("UserServiceImpl.setAuthCode params : {}, {}, {}", phone, code);
        Jedis jedis = connectionFactory.fetchJedisConnector();
        try {
            return jedis.setex(phone, seconds, code).equalsIgnoreCase("ok") ? "发送成功！" : "发送失败！";
        } finally {
            jedis.close();
        }
    }

    @Override
    public boolean alreadyExists(String phone) {
        Jedis jedis = connectionFactory.fetchJedisConnector();
        try {
            return StringUtils.isNotBlank(jedis.get(phone)) == true ? true : false;
        } finally {
            jedis.close();
        }
    }

    @Override
    public String captcha(String phone) throws Exception {
        // 判断用户是否注册
        UserBO user = getUserByPhone(phone);
        if (Objects.equals(user, null)) {
            throw new BusinessException("用户未注册或未激活！");
        }
        // 发送验证码
        return sendMessageService.sendCaptcha(phone);
    }

    @Override
    public UserBO getUserByPhone(String phone) throws Exception {
        LOGGER.info("UserServiceImpl.getUserByPhone param phone: {}", phone);
        if (StringUtils.isBlank(phone)) {
            LOGGER.info("UserServiceImpl.getUserByPhone param phone must not be null");
            throw new IllegalArgumentException("手机号不能为空");
        }
        SaleUserExample example = new SaleUserExample();
        example.createCriteria().andPhoneEqualTo(phone).andEnableEqualTo(true);
        List<SaleUser> users = userMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(users)) {
            SaleUser user = users.get(0);
            UserBO bo = new UserBO();
            BeanUtils.copyProperties(user, bo);
            return bo;
        }
        return null;
    }

    @Override
    public String getAuthCode(String phone) throws Exception {
        LOGGER.info("UserServiceImpl.getAuthCode param : {}, {}", phone);
        Jedis jedis = connectionFactory.fetchJedisConnector();
        String code;
        try {
            code = jedis.get(phone);
            LOGGER.info("UserServiceImpl.getAuthCode return : {}", code);
        } finally {
            jedis.close();
        }
        return code;
    }

    @Override
    public Boolean removeAuthcode(String key) {
        LOGGER.info("UserServiceImpl.removeAuthcode param : {}", key);
        Jedis jedis = connectionFactory.fetchJedisConnector();
        try {
            return jedis.del(key) > 0 ? true : false;
        } finally {
            jedis.close();
        }
    }

    @Override
    public Integer restPwd(String phone, String pwd, String authcode) throws Exception {
        LOGGER.info("UserServiceImpl.restPwd params phone: {}, pwd: {}, authcode: {}", phone, pwd, authcode);
        if (StringUtils.isBlank(phone)) {
            LOGGER.info("UserServiceImpl.restPwd param phone must not be null");
            throw new IllegalArgumentException("手机号不能为空");
        } else if (StringUtils.isBlank(pwd)) {
            LOGGER.info("UserServiceImpl.restPwd param pwd must not be null");
            throw new IllegalArgumentException("密码不能为空");
        } else if (StringUtils.isBlank(authcode)) {
            LOGGER.info("UserServiceImpl.restPwd param authcode must not be null");
            throw new IllegalArgumentException("验证码不能为空");
        }
        String code = getAuthCode(phone);
        if (!authcode.equals(code)) {
            LOGGER.info("UserServiceImpl.restPwd Authcode error");
            throw new BusinessException("验证码错误，请重新输入");
        }
        UserBO bo = getUserByPhone(phone);
        if (Objects.equals(bo, null)) {
            LOGGER.info("UserServiceImpl.restPwd current user doesn't exist");
            throw new BusinessException("当前用户不存在");
        }
        String key = autoConfConstant.getSecure();
        bo.setPwd(passwordEncoder.encodePassword(pwd, key));
        SaleUser user = new SaleUser();
        BeanUtils.copyProperties(bo, user);
        userMapper.updateByPrimaryKeySelective(user);
        removeAuthcode(phone);
        return null;
    }

    @Override
    public UserViewBO getUserByCondition(Integer id, String loginName, String phone) throws Exception {
        LOGGER.info("UserServiceImpl.getUserByCondition params id: {}, loginName: {}, phone: {}", id, loginName, phone);
        if (Objects.equals(id, null) && StringUtils.isBlank(loginName) && StringUtils.isBlank(phone)) {
            LOGGER.info("UserServiceImpl.getUserByCondition Have to enter a query conditions");
            throw new IllegalArgumentException("必须输入一个查询条件");
        }
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("id", id);
        queryMap.put("loginName", loginName);
        queryMap.put("phone", phone);
        try {
            UserViewDAO dao = userViewMapper.getUserByCondition(queryMap);
            UserViewBO bo = new UserViewBO();
            BeanUtils.copyProperties(dao, bo);
            bo.setPicUrl(QiniuUtil.generateDownloadURL(QiniuConstant.QINIU_DOWNLOAD_ADDRESS, bo.getPicKey(), "", null, null));
            return bo;
        } catch (Exception e) {
            LOGGER.error("UserServiceImpl.getUserByCondition error: {}", e);
            throw new BusinessException("查询用户信息异常");
        }
    }

    @Override
    public UserViewBO getCurrentUser() throws Exception {
        return getUserByCondition(Integer.valueOf(getUser().getId() + ""), null,null);
    }

    @Override
    public List<UserBO> listUser() throws Exception {
        SaleUserExample example = new SaleUserExample();
        example.createCriteria().andEnableEqualTo(true);
        List<SaleUser> users = null;
        try {
            users = userMapper.selectByExample(example);
        } catch (Exception e) {
            LOGGER.error("UserServiceImpl.listUser error: {}", e);
            throw new BusinessException("查询销售人员列表异常");
        }
        List<UserBO> userBOS = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(users)) {
            if (CollectionUtils.isNotEmpty(users)) {
                users.stream().forEach(val -> {
                    UserBO bo = new UserBO();
                    BeanUtils.copyProperties(val, bo);
                    userBOS.add(bo);
                });
            }
        }
        return userBOS;
    }

    private UserSecurityVO getUser() throws Exception {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            return (UserSecurityVO)authentication.getPrincipal();
        } catch (Exception e) {
            LOGGER.error("UserServiceImpl.getCurrentUserVo error : {}", e);
            throw new BusinessException("获取当前用户信息异常！");
        }
    }

}
